package com.itbaizhan.cxpt.service;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.itbaizhan.cxpt.common.Result;
import com.itbaizhan.cxpt.entity.FileDesc;
import com.itbaizhan.cxpt.entity.GbStandardAnalysis;
import com.itbaizhan.cxpt.entity.Standard;
import com.itbaizhan.cxpt.mapper.CxptBzMapper;
import com.itbaizhan.cxpt.mapper.FileDescMapper;
import com.itbaizhan.cxpt.mapper.GbStandardAnalysisMapper;
import com.itbaizhan.cxpt.parser.StandardJsonParser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.InputStreamResource;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;

import java.io.InputStream;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.itbaizhan.cxpt.entity.FileUploadRecord;
import com.itbaizhan.cxpt.mapper.FileUploadRecordMapper;

@Service
public class PdfAnalyzeService {

    @Autowired
    private FileUploadRecordMapper fileUploadRecordMapper;

    @Autowired
    private CxptBzMapper cxptBzMapper;

    @Autowired
    private FileDescMapper fileDescMapper;

    @Value("${moonshot.api.key}")
    private String apiKey;

    @Value("${moonshot.api.url}")
    private String url;

    @Value("${moonshot.api.base-url}")
    private String baseUrl;

    @Value("${moonshot.api.endpoints.files}")
    private String filesEndpoint;


    private final RestTemplate restTemplate = new RestTemplate();

    /**
     * 上传文件
     * @param file
     * @return
     */
    public Result analyzePdf(MultipartFile file) {
        try {
            // 检查文件是否已存在
            String fileName = file.getOriginalFilename();
            if (fileUploadRecordMapper.existsByFileName(fileName,file.getSize())) {
                return Result.error("文件已经上传过，请勿重复上传");
            }
            // 第一步：上传文件
           return  uploadFile(file);
        } catch (Exception e) {
            return Result.error("处理过程中发生错误: " + e.getMessage());
        }
    }

    /**
     * 解析文件获取结果
     * @param fileId
     * @return
     */
    public Result analyzeByFileId(String fileId) {
        try {
            // 检查文件记录是否存在
            FileUploadRecord record = fileUploadRecordMapper.findByFileId(fileId);
            if (record == null) {
                return Result.error("文件记录不存在");
            }
            List<FileDesc> byFileId = fileDescMapper.findByFileId(record.getId());
            if (!CollectionUtils.isEmpty(byFileId)) {
                return Result.error("已经解析过了不用重复解析" );
            }
            // 获取文件内容
           return   getFileContent(record);
        } catch (Exception e) {
            e.printStackTrace();
            return Result.error("处理过程中发生错误:" + e.getMessage());
        }
    }

    /**
     * 文件上传
     * @param file
     * @return
     */
    private Result uploadFile(MultipartFile file) {
        try {
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.MULTIPART_FORM_DATA);
            headers.set("Authorization", "Bearer " + apiKey);

            MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
            body.add("file", new MultipartInputStreamFileResource(file.getInputStream(), file.getOriginalFilename()));
            body.add("purpose", "file-extract");

            HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(body, headers);
            Map<String, Object> response = restTemplate.postForObject(baseUrl + filesEndpoint, requestEntity, Map.class);

            if (response != null && response.containsKey("id")) {
                String fileId = response.get("id").toString();
                // 保存文件上传记录
                FileUploadRecord record = new FileUploadRecord();
                record.setFileName(file.getOriginalFilename());
                record.setUploadTime(LocalDateTime.now());
                record.setFileId(fileId);
                record.setStatus(1); // 上传成功
                record.setFileSize(file.getSize());
                fileUploadRecordMapper.insert(record);
                return Result.success("success");
            }
            return Result.error("error");
        } catch (Exception e) {
            return Result.error("error");
        }
    }

    /**
     * 解析pdf文件内容
     * @param fileUploadRecord
     * @return
     * @throws Exception
     */
    @Transactional
    Result getFileContent(FileUploadRecord fileUploadRecord) throws Exception {
        // 创建 RestTemplate 实例
        RestTemplate restTemplate = new RestTemplate();

        // 设置请求头
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        headers.setBearerAuth(apiKey);  // 设置 Authorization: Bearer token

        // 构建请求体 Map
        Map<String, Object> requestBody = new HashMap<>();
        requestBody.put("model", "qwen-long");

        // 构建 messages 数组
        List<Map<String, String>> messages = new ArrayList<>();
        messages.add(Map.of("role", "system", "content", "你是一个专门用于分析PDF文件中国标信息的AI助手。请仔细分析内容中的国标信息，提取以下信息：\n1. 标准号（完整的国标编号）\n2. 标准名称（完整的标准名称）\n3. 在PDF中的页码\n请以JSON格式返回，包含standardNo、standardName和page字段。"));
        messages.add(Map.of("role", "system", "content", "fileid://"+fileUploadRecord.getFileId()));
        messages.add(Map.of("role", "user", "content", "获取文档中的所有国标信息.我要文档的全部国标信息. 不要有遗漏.只需要JSON数据别的无关字符不要返回"));
        requestBody.put("messages", messages);

        // 将请求体转换成 JSON 字符串
        ObjectMapper objectMapper = new ObjectMapper();
        String jsonBody = objectMapper.writeValueAsString(requestBody);

        // 构建 HttpEntity
        HttpEntity<String> entity = new HttpEntity<>(jsonBody, headers);

        // 发送 POST 请求
        ResponseEntity<String> response = restTemplate.exchange(
                url,
                HttpMethod.POST,
                entity,
                String.class
        );
        // 输出响应内容
        System.out.println(response.getBody());

        List<Standard> standards = StandardJsonParser.parseStandards(response.getBody());
        if (!CollectionUtils.isEmpty(standards)){
            for (Standard standard : standards) {
                FileDesc fileDesc = new FileDesc();
                fileDesc.setA100(standard.getStandardNo());
                fileDesc.setA298(standard.getStandardName());
                fileDesc.setFileId(fileUploadRecord.getId());
                fileDesc.setFilePage(standard.getPage());
                fileDescMapper.insert(fileDesc);
            }
            // 状态：1-上传成功， 2 解析成功  3 分析完成
            fileUploadRecord.setStatus(2);
            fileUploadRecordMapper.updateById(fileUploadRecord);
             return Result.success( "文件解析成功");
        }
         return Result.error("错误");
    }


    /**
     * 分析内容
     * @param fileid
     * @return
     */
    public Result analyzeFileContent(String fileid) {
        // 检查文件记录是否存在
        FileUploadRecord record = fileUploadRecordMapper.findByFileId(fileid);
        if (record == null) {
            return Result.error("文件不存在");
        }
        // 分析完成
        if (record.getStatus() == 3) {
            return Result.success(fileDescMapper.findByFileId(record.getId()));
        }
        List<FileDesc> fileDescList = fileDescMapper.findByFileId(record.getId());
        if (!CollectionUtils.isEmpty(fileDescList)) {
            boolean allMatch = true; // 用于跟踪所有标准是否都匹配
            
            for (FileDesc fileDesc : fileDescList) {
                // 国标号
                String a100 = fileDesc.getA100();
                // 根据国标号模糊查询数据库中的记录
                List<Map<String, Object>> dbRecords = cxptBzMapper.findByA100Like(a100);
                
                if (CollectionUtils.isEmpty(dbRecords)) {
                    // 数据库中没有找到匹配的记录
                    fileDesc.setFileResult("数据库中未找到该标准号");
                    fileDesc.setFileStatus(0); // 设置为不符合
                    allMatch = false;
                } else {
                    boolean nameMatched = false;
                    StringBuilder resultBuilder = new StringBuilder();
                    
                    for (Map<String, Object> dbRecord : dbRecords) {
                        String dbA298 = (String) dbRecord.get("a298");
                        String dbA100 = (String) dbRecord.get("a100");
                        
                        // 比较标准名称是否一致
                        if (fileDesc.getA298().equals(dbA298)) {
                            nameMatched = true;
                            break;
                        } else {
                            resultBuilder.append("数据库中标准号[")
                                       .append(dbA100)
                                       .append("]对应的标准名称为[")
                                       .append(dbA298)
                                       .append("]，与文件中的标准名称[")
                                       .append(fileDesc.getA298())
                                       .append("]不一致\n");
                        }
                    }
                    
                    if (!nameMatched) {
                        fileDesc.setFileResult(resultBuilder.toString());
                        fileDesc.setFileStatus(0); // 设置为不符合
                        allMatch = false;
                    } else {
                        fileDesc.setFileResult("标准号和标准名称与数据库记录一致");
                        fileDesc.setFileStatus(1); // 设置为符合
                    }
                }
                // 更新分析结果
                fileDescMapper.updateById(fileDesc);
            }
            record.setStatus(3);
            fileUploadRecordMapper.updateById(record);
            return Result.success(fileDescList);
        }
        return Result.error("没有找到解析记录");
    }


    private static class MultipartInputStreamFileResource extends InputStreamResource {
        private final String filename;

        public MultipartInputStreamFileResource(InputStream inputStream, String filename) {
            super(inputStream);
            this.filename = filename;
        }

        @Override
        public String getFilename() {
            return this.filename;
        }

        @Override
        public long contentLength() {
            return -1; // 表示长度未知
        }
    }
}